package Client;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RemoteServer;

import General.MainShipQuoterServiceInterface;
import General.Product;
import General.QuoteInterface;

public class Client {
	
	private static int CLIENT_ID = 1;
	private int fClientId;
	private String fHost;
	private String fRegistryIp;
	private int fRegistryPort;
	private Registry fRegistry;
	
	public Client(String host, String registryIp, int registryPort) {	
		fHost = host;
		fRegistryPort = registryPort;
		fClientId = CLIENT_ID;
		CLIENT_ID++;
		fRegistryIp = registryIp;
		try {
			fRegistry = LocateRegistry.getRegistry(fRegistryIp, fRegistryPort);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	public void start() {
		try {	
			
			//Set up log file
			try {
				FileOutputStream logFile = new FileOutputStream("client.log");
				RemoteServer.setLog(logFile);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			
			// Look up MainShipQuoteService
			MainShipQuoterServiceInterface quoter = (MainShipQuoterServiceInterface)fRegistry.lookup("MainShipQuoteService");
			
			// Output
			System.out.println("[CLIENT] Client started on host " + fHost);
			
			// Make product MakeBookPro and quote price
			Product product = new Product("MacBook Pro", 2, "Mechelsesteenweg 222 2650 Edegem", "Ringlaan 1 Wilrijk", 20, 60, 10, 1200, "EUR", false, Product.AIR); 
			System.out.println("[CLIENT] Quote product with id " + product.getId());
			QuoteInterface quote = quoter.quote(product);
			System.out.println("[CLIENT] The price for the shipment is " + quote.getPrice() + " " + quote.getCurrency());
			
			// Send product MakeBookPro
			ClientNotificatorService clientNotificator = new ClientNotificatorService();
			ClientEventHandler clientEventNotificator = new ClientEventHandler(clientNotificator, fClientId);
			System.out.println("[CLIENT] Request for shipping sent to server for product with id " + product.getId());
			if (quoter.requestForShipping(product, clientEventNotificator)) {
				System.out.println("[CLIENT] The request for shipment has been accepted");
			} else {
				System.out.println("[CLIENT] The request for shipment has been denied");
			}
			
			// Send product kitchen table
			Product product2 = new Product("Kitchen table", 7, "Mechelsesteenweg 222 2650 Edegem", "Ringlaan 1 Wilrijk", 200, 170, 80, 4000, "EUR", false, Product.GROUND); 
			System.out.println("[CLIENT] Request for shipping sent to server for product with id " + product2.getId());
			if (quoter.requestForShipping(product2, clientEventNotificator)) {
				System.out.println("[CLIENT] The request for shipment has been accepted");
			} else {
				System.out.println("[CLIENT] The request for shipment has been denied");
			}
			
			// Send product football after 30 seconds
			try {
				Thread.sleep(30000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Product product3 = new Product("Football", 1, "Mechelsesteenweg 222 2650 Edegem", "Ringlaan 1 Wilrijk", 20, 20, 20, 50, "EUR", false, Product.GROUND); 
			System.out.println("[CLIENT] Request for shipping sent to server for product with id " + product3.getId());
			if (quoter.requestForShipping(product3, clientEventNotificator)) {
				System.out.println("[CLIENT] The request for shipment has been accepted");
			} else {
				System.out.println("[CLIENT] The request for shipment has been denied");
			}
			
			// Track states
			System.out.println("[CLIENT] Track state for product with id " + product2.getId());
			System.out.println("[CLIENT] The state for product with id " + product2.getId() + " is " + Product.getStateName(quoter.getState(product2.getId())));
			System.out.println("[CLIENT] Track state for product with id " + product3.getId());
			System.out.println("[CLIENT] The state for product with id " + product3.getId() + " is " + Product.getStateName(quoter.getState(product3.getId())));
			
			// Try to send hazardous good with air-priority
			Product product4 = new Product("Kitchen table", 7, "Mechelsesteenweg 222 2650 Edegem", "Ringlaan 1 Wilrijk", 200, 170, 80, 4000, "EUR", true, Product.AIR_PRIORITY); 
			System.out.println("[CLIENT] Request for shipping sent to server for product with id " + product4.getId());
			if (quoter.requestForShipping(product4, clientEventNotificator)) {
				System.out.println("[CLIENT] The request for shipment has been accepted");
			} else {
				System.out.println("[CLIENT] The request for shipment has been denied");
			}
			
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (NotBoundException e) {
			e.printStackTrace(); 
		} 
	}
	
	public int getClientId() {
		return fClientId;
	}
	
	public void printRegistryServices() {
		try {
			System.out.println("[CLIENT] Services registred at registry:");
			String[] services = fRegistry.list();
			for (int i = 0; i < services.length; i++) {
				System.out.println("[CLIENT] " + services[i]);
			}
		} catch (AccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
